package com.nervenets.web.controller.setting;

import com.nervenets.Global;
import com.nervenets.utils.ImageHelper;
import com.nervenets.utils.JodaUtils;
import com.nervenets.utils.PropertiesLoader;
import com.nervenets.web.controller.BaseController;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.entity.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;

/**
 * Created by Joe
 * Date: 13-2-21 下午8:50
 * Email: joesupper@vip.qq.com
 */
@Api(value = "文件接口v1", description = "文件相关接口")
@RestController
@RequestMapping("/api/v1/file")
public class UploadController extends BaseController {

    @ApiOperation("上传文件，参数userfile")
    @PostMapping("/upload")
    protected ResponseResult upload(@RequestParam("userfile") MultipartFile userfile, HttpServletRequest request) throws Exception {
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        System.out.println(isMultipart);
        if (!isMultipart) return errorMessage(MessageCode.code_403);

        if (userfile.getSize() == 0) {
            return errorMessage(MessageCode.code_403, "文件大小为0");
        }

        int x = ServletRequestUtils.getIntParameter(request, "x", 0);
        int y = ServletRequestUtils.getIntParameter(request, "y", 0);
        int w = ServletRequestUtils.getIntParameter(request, "w", 0);
        int h = ServletRequestUtils.getIntParameter(request, "h", 0);
        if (x < 0) x = 0;
        if (y < 0) y = 0;
        if (w < 0) w = 0;
        if (h < 0) h = 0;
        String originalFilename = userfile.getOriginalFilename();
        System.out.println(originalFilename);
        int i = originalFilename.lastIndexOf(".");
        if (i < 0) return errorMessage(MessageCode.code_444);
        String suffix = originalFilename.substring(i);
        final String uploadFile = uploadFile(userfile.getBytes(), suffix);
        final PropertiesLoader propertiesLoader = Global.getApplicationProperties();
        if (w > 0 && h > 0) {
            StringBuilder buffer = new StringBuilder();
            buffer.append(propertiesLoader.getProperty("api.upload.folder")).append(File.separatorChar).append("upload").append(File.separatorChar).append(JodaUtils.getStartOfToday()).append(File.separatorChar);
            final String dir = buffer.toString();
            buffer.append(uploadFile);
            ImageHelper.cutImage(buffer.toString(), dir + "cut_" + uploadFile, x, y, w, h);
            return successMessage("https://" + propertiesLoader.getProperty("api.upload.domain") + "/upload/" + JodaUtils.getStartOfToday() + "/" + "cut_" + uploadFile);
        }
        return successMessage("https://" + propertiesLoader.getProperty("api.upload.domain") + "/upload/" + JodaUtils.getStartOfToday() + "/" + uploadFile);
    }

    @ApiOperation("base64上传文件，参数base64str")
    @PostMapping("/base64Upload")
    public ResponseResult base64Upload(@RequestBody UploadParams params) throws Exception {
        final Set<ConstraintViolation<UploadParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        BASE64Decoder decoder = new BASE64Decoder();
        try {
            final PropertiesLoader propertiesLoader = Global.getApplicationProperties();
            //Base64解码
            String base64Mark = "base64,";
            int indexOf = params.getBase64Str().indexOf(base64Mark);
            if (-1 == indexOf) return errorMessage(MessageCode.code_444, "base64字符串不合法");
            byte[] b = decoder.decodeBuffer(params.getBase64Str().substring(indexOf + base64Mark.length()));
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {//调整异常数据
                    b[i] += 256;
                }
            }
            //生成jpeg图片
            StringBuilder buffer = new StringBuilder();
            buffer.append(propertiesLoader.getProperty("api.upload.folder")).append(File.separatorChar).append("upload").append(File.separatorChar).append(JodaUtils.getStartOfToday()).append(File.separatorChar);
            if (!new File(buffer.toString()).exists()) {
                new File(buffer.toString()).mkdirs();
            }
            final String dir = buffer.toString();
            String uploadFile = System.currentTimeMillis() + ".jpg";
            buffer.append(uploadFile);
            OutputStream out = new FileOutputStream(buffer.toString());
            out.write(b);
            out.flush();
            out.close();

            if (params.getW() > 0 && params.getH() > 0) {
                ImageHelper.cutImage(buffer.toString(), dir + "cut_" + uploadFile, params.getX(), params.getY(), params.getW(), params.getH());
                return successMessage("https://" + propertiesLoader.getProperty("api.upload.domain") + "/upload/" + JodaUtils.getStartOfToday() + "/" + "cut_" + uploadFile);
            }

            return successMessage("https://" + propertiesLoader.getProperty("api.upload.domain") + "/upload/" + JodaUtils.getStartOfToday() + "/" + uploadFile);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return errorMessage(MessageCode.code_500);
        }
    }

    private String getFileHexString(byte[] b) {
        StringBuilder stringBuilder = new StringBuilder();
        if (b == null || b.length <= 0) {
            return null;
        }
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    class UMEditorUploadModel {
        private String state = "SUCCESS";
        private String url;

        UMEditorUploadModel(String url) {
            this.url = url;
        }
    }


    private String generateFileName(long timeMillis, boolean check, String suffix) throws IllegalAccessException {
        final PropertiesLoader propertiesLoader = Global.getApplicationProperties();
        StringBuilder buffer = new StringBuilder();
        buffer.append(propertiesLoader.getProperty("api.upload.folder")).append(File.separatorChar).append("upload").append(File.separatorChar).append(JodaUtils.getStartOfToday()).append(File.separatorChar);
        File dir = new File(buffer.toString());
        if (!dir.exists()) {
            dir.mkdirs();
        }
        buffer.append(timeMillis).append(suffix);
        File file = new File(buffer.toString());
        if (file.exists() && check) return null;
        return buffer.toString();
    }

    private String uploadFile(byte[] bytes, String suffix) throws IllegalAccessException, IOException {
        String fileName = null;
        long timeMillis;
        do {
            timeMillis = System.currentTimeMillis();
            fileName = generateFileName(timeMillis, true, suffix);
        } while (fileName == null);

        File picture = new File(fileName);
        // now make it
        OutputStream out = new FileOutputStream(picture.getAbsolutePath());
        out.write(bytes);
        out.close();
        return timeMillis + suffix;
    }

    private boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (String aTempList : tempList) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + aTempList);
            } else {
                temp = new File(path + File.separator + aTempList);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + aTempList);
                delFolder(path + "/" + aTempList);
                flag = true;
            }
        }
        return flag;
    }

    private void delFolder(String folderPath) {
        try {
            delAllFile(folderPath);
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}
